' This class holds the data we will pass to each thread
Public Class MyThreadData
' This worker thread name
Public Name As String
' Barcode reader instance
Public BarcodeReaderInstance As BarcodeReader
' Array of options to use
Public ReadOptions() As BarcodeReadOptions
' Image file containing the barcodes
Public ImageFileName As String
' This will hold the barcodes found
Public Barcodes() As BarcodeData
' In case of errors
Public Err As Exception
' Event to notify when the thread is finished
Public FinishedEvent As AutoResetEvent
End Class
Public Sub BarcodeReader_ReadBarcodeExample6()
Dim imageFileNames() As String = PrepareImages()
' Create a Barcode engine
Dim engine As New BarcodeEngine()
' Get the Barcode reader instance
Dim reader As BarcodeReader = engine.Reader
' Get a version of all read options that support rotated barcodes
Dim verticalBarcodeReadOptions() As BarcodeReadOptions = GetVerticalReadBarcodeOptions(reader)
' Synchronization events
Dim finishedEvents(2) As AutoResetEvent
' Create the thread data objects
Dim threadsData(2) As MyThreadData
For i As Integer = 0 To threadsData.Length - 1
finishedEvents(i) = New AutoResetEvent(False)
threadsData(i) = New MyThreadData()
threadsData(i).BarcodeReaderInstance = reader
threadsData(i).ReadOptions = Nothing
threadsData(i).FinishedEvent = finishedEvents(i)
Next
' Setup the read options for the two threads
threadsData(0).Name = "Read Default Options Thread"
threadsData(0).ReadOptions = Nothing ' Default, or horizontal
threadsData(1).Name = "Read Vertical Barcodes Thread"
threadsData(1).ReadOptions = verticalBarcodeReadOptions
Dim totalBarcodes As New List(Of BarcodeData)()
' Now loop through all the images and try to read the barcodes with both threads at the same time
For Each imageFileName As String In imageFileNames
Console.WriteLine("Reading barcodes from {0}", imageFileName)
For i As Integer = 0 To 1
' Clear the previous results (if any), set up the file name and run
threadsData(i).Barcodes = Nothing
threadsData(i).Err = Nothing
threadsData(i).ImageFileName = imageFileName
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf ReadBarcodesInThread), threadsData(i))
Next
' Wait till all the threads finishes
WaitHandle.WaitAll(finishedEvents)
' Add the barcodes found to our list
For i As Integer = 0 To 1
If Not IsNothing(threadsData(i).Err) Then
Console.WriteLine("{0} had error {1}", threadsData(i).Name, threadsData(i).Err)
ElseIf Not IsNothing(threadsData(i).Barcodes) Then
totalBarcodes.AddRange(threadsData(i).Barcodes)
End If
Next
Next
' We are done, show the total number of barcodes read
Console.WriteLine("Done. Total barcodes read: {0}", totalBarcodes.Count)
End Sub
Private Shared Sub ReadBarcodesInThread(ByVal state As Object)
Dim threadData As MyThreadData = DirectCast(state, MyThreadData)
Console.WriteLine("{0} is reading the barcodes", threadData.Name)
Try
' Load the image
Using codecs As New RasterCodecs()
Using image As RasterImage = codecs.Load(threadData.ImageFileName, 0, CodecsLoadByteOrder.BgrOrGray, 1, 1)
' Read the barcodes using our options
threadData.Barcodes = threadData.BarcodeReaderInstance.ReadBarcodes(image, LogicalRectangle.Empty, 0, Nothing, threadData.ReadOptions)
End Using
End Using
Console.WriteLine("{0} has read {1} barcodes", threadData.Name, threadData.Barcodes.Length)
Catch ex As Exception
' Return the error to main
threadData.Err = ex
Finally
' Tell main we are done
threadData.FinishedEvent.Set()
End Try
End Sub
Private Shared Function PrepareImages() As String()
' Create a 90 degrees rotated version of Barcode1.tif
Dim originalImageFileName As String = Path.Combine(LEAD_VARS.ImagesDir, "Barcode1.tif")
Dim rotatedImageFileName As String = Path.Combine(LEAD_VARS.ImagesDir, "Barcode1_Rotated90.tif")
Using codecs As New RasterCodecs()
Using image As RasterImage = codecs.Load(originalImageFileName, 0, CodecsLoadByteOrder.BgrOrGray, 1, 1)
Dim rotate As New RotateCommand(90 * 100, RotateCommandFlags.Resize, RasterColor.FromKnownColor(RasterKnownColor.White))
rotate.Run(image)
codecs.Save(image, rotatedImageFileName, RasterImageFormat.CcittGroup4, 1)
End Using
End Using
Return New String() {originalImageFileName, rotatedImageFileName}
End Function
Private Shared Function GetVerticalReadBarcodeOptions(ByVal reader As BarcodeReader) As BarcodeReadOptions()
' By default, the options read horizontal barcodes only, create an array of options capable of reading vertical barcodes
' Notice, we cloned the default options in reader so we will not change the original options
Dim oneDReadOptions As OneDBarcodeReadOptions = DirectCast(reader.GetDefaultOptions(BarcodeSymbology.UPCA).Clone(), OneDBarcodeReadOptions)
oneDReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
Dim fourStateReadOptions As FourStateBarcodeReadOptions = DirectCast(reader.GetDefaultOptions(BarcodeSymbology.USPS4State).Clone(), FourStateBarcodeReadOptions)
fourStateReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
Dim postNetPlanetReadOptions As PostNetPlanetBarcodeReadOptions = DirectCast(reader.GetDefaultOptions(BarcodeSymbology.PostNet).Clone(), PostNetPlanetBarcodeReadOptions)
postNetPlanetReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
Dim gs1StackedReadOptions As GS1DatabarStackedBarcodeReadOptions = DirectCast(reader.GetDefaultOptions(BarcodeSymbology.GS1DatabarStacked).Clone(), GS1DatabarStackedBarcodeReadOptions)
gs1StackedReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
Dim patchCodeReadOptions As PatchCodeBarcodeReadOptions = DirectCast(reader.GetDefaultOptions(BarcodeSymbology.PatchCode).Clone(), PatchCodeBarcodeReadOptions)
patchCodeReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
Dim pdf417ReadOptions As PDF417BarcodeReadOptions = DirectCast(reader.GetDefaultOptions(BarcodeSymbology.PDF417).Clone(), PDF417BarcodeReadOptions)
pdf417ReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
Dim microPdf417ReadOptions As MicroPDF417BarcodeReadOptions = DirectCast(reader.GetDefaultOptions(BarcodeSymbology.MicroPDF417).Clone(), MicroPDF417BarcodeReadOptions)
microPdf417ReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
' Even though this array will not contain all options, it should be enough to read all barcodes, since the version of ReadBarcodes we will use
' will use the default options if an overriden is not passed
Dim readOptions() As BarcodeReadOptions = _
{ _
oneDReadOptions, fourStateReadOptions, postNetPlanetReadOptions, gs1StackedReadOptions, patchCodeReadOptions, pdf417ReadOptions, microPdf417ReadOptions _
}
Return readOptions
End Function
Public NotInheritable Class LEAD_VARS
Public Const ImagesDir As String = "C:\Users\Public\Documents\LEADTOOLS Images"
End Class
// This class holds the data we will pass to each thread
public class MyThreadData
{
// This worker thread name
public string Name;
// Barcode reader instance
public BarcodeReader BarcodeReaderInstance;
// Array of options to use
public BarcodeReadOptions[] ReadOptions;
// Image file containing the barcodes
public string ImageFileName;
// This will hold the barcodes found
public BarcodeData[] Barcodes;
// In case of errors
public Exception Error;
// Event to notify when the thread is finished
public AutoResetEvent FinishedEvent;
}
public void BarcodeReader_ReadBarcodeExample6()
{
string[] imageFileNames = PrepareImages();
// Create a Barcode engine
BarcodeEngine engine = new BarcodeEngine();
// Get the Barcode reader instance
BarcodeReader reader = engine.Reader;
// Get a version of all read options that support rotated barcodes
BarcodeReadOptions[] verticalBarcodeReadOptions = GetVerticalReadBarcodeOptions(reader);
// Synchronization events
AutoResetEvent[] finishedEvents = new AutoResetEvent[2];
// Create the thread data objects
MyThreadData[] threadsData = new MyThreadData[2];
for(int i = 0; i < threadsData.Length; i++)
{
finishedEvents[i] = new AutoResetEvent(false);
threadsData[i] = new MyThreadData();
threadsData[i].BarcodeReaderInstance = reader;
threadsData[i].ReadOptions = null;
threadsData[i].FinishedEvent = finishedEvents[i];
}
// Setup the read options for the two threads
threadsData[0].Name = "Read Default Options Thread";
threadsData[0].ReadOptions = null; // Default, or horizontal
threadsData[1].Name = "Read Vertical Barcodes Thread";
threadsData[1].ReadOptions = verticalBarcodeReadOptions;
List<BarcodeData> totalBarcodes = new List<BarcodeData>();
// Now loop through all the images and try to read the barcodes with both threads at the same time
foreach(string imageFileName in imageFileNames)
{
Console.WriteLine("Reading barcodes from {0}", imageFileName);
for(int i = 0; i < 2; i++)
{
// Clear the previous results (if any), set up the file name and run
threadsData[i].Barcodes = null;
threadsData[i].Error = null;
threadsData[i].ImageFileName = imageFileName;
ThreadPool.QueueUserWorkItem(new WaitCallback(ReadBarcodesInThread), threadsData[i]);
}
// Wait till all the threads finishes
WaitHandle.WaitAll(finishedEvents);
// Add the barcodes found to our list
for(int i = 0; i < 2; i++)
{
if(threadsData[i].Error != null)
{
Console.WriteLine("{0} had error {1}", threadsData[i].Name, threadsData[i].Error);
}
else if(threadsData[i].Barcodes != null)
{
totalBarcodes.AddRange(threadsData[i].Barcodes);
}
}
}
// We are done, show the total number of barcodes read
Console.WriteLine("Done. Total barcodes read: {0}", totalBarcodes.Count);
}
private static void ReadBarcodesInThread(object state)
{
MyThreadData threadData = state as MyThreadData;
Console.WriteLine("{0} is reading the barcodes", threadData.Name);
try
{
// Load the image
using(RasterCodecs codecs = new RasterCodecs())
{
using(RasterImage image = codecs.Load(threadData.ImageFileName, 0, CodecsLoadByteOrder.BgrOrGray, 1, 1))
{
// Read the barcodes using our options
threadData.Barcodes = threadData.BarcodeReaderInstance.ReadBarcodes(image, LogicalRectangle.Empty, 0, null, threadData.ReadOptions);
}
}
Console.WriteLine("{0} has read {1} barcodes", threadData.Name, threadData.Barcodes.Length);
}
catch(Exception ex)
{
// Return the error to main
threadData.Error = ex;
}
finally
{
// Tell main we are done
threadData.FinishedEvent.Set();
}
}
private static string[] PrepareImages()
{
// Create a 90 degrees rotated version of Barcode1.tif
string originalImageFileName = Path.Combine(LEAD_VARS.ImagesDir, "Barcode1.tif");
string rotatedImageFileName = Path.Combine(LEAD_VARS.ImagesDir, "Barcode1_Rotated90.tif");
using(RasterCodecs codecs = new RasterCodecs())
{
using(RasterImage image = codecs.Load(originalImageFileName, 0, CodecsLoadByteOrder.BgrOrGray, 1, 1))
{
RotateCommand rotate = new RotateCommand(90 * 100, RotateCommandFlags.Resize, RasterColor.FromKnownColor(RasterKnownColor.White));
rotate.Run(image);
codecs.Save(image, rotatedImageFileName, RasterImageFormat.CcittGroup4, 1);
}
}
return new string[] { originalImageFileName, rotatedImageFileName };
}
private static BarcodeReadOptions[] GetVerticalReadBarcodeOptions(BarcodeReader reader)
{
// By default, the options read horizontal barcodes only, create an array of options capable of reading vertical barcodes
// Notice, we cloned the default options in reader so we will not change the original options
OneDBarcodeReadOptions oneDReadOptions = reader.GetDefaultOptions(BarcodeSymbology.UPCA).Clone() as OneDBarcodeReadOptions;
oneDReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
FourStateBarcodeReadOptions fourStateReadOptions = reader.GetDefaultOptions(BarcodeSymbology.USPS4State).Clone() as FourStateBarcodeReadOptions;
fourStateReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
PostNetPlanetBarcodeReadOptions postNetPlanetReadOptions = reader.GetDefaultOptions(BarcodeSymbology.PostNet).Clone() as PostNetPlanetBarcodeReadOptions;
postNetPlanetReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
GS1DatabarStackedBarcodeReadOptions gs1StackedReadOptions = reader.GetDefaultOptions(BarcodeSymbology.GS1DatabarStacked).Clone() as GS1DatabarStackedBarcodeReadOptions;
gs1StackedReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
PatchCodeBarcodeReadOptions patchCodeReadOptions = reader.GetDefaultOptions(BarcodeSymbology.PatchCode).Clone() as PatchCodeBarcodeReadOptions;
patchCodeReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
PDF417BarcodeReadOptions pdf417ReadOptions = reader.GetDefaultOptions(BarcodeSymbology.PDF417).Clone() as PDF417BarcodeReadOptions;
pdf417ReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
MicroPDF417BarcodeReadOptions microPdf417ReadOptions = reader.GetDefaultOptions(BarcodeSymbology.MicroPDF417).Clone() as MicroPDF417BarcodeReadOptions;
microPdf417ReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
// Even though this array will not contain all options, it should be enough to read all barcodes, since the version of ReadBarcodes we will use
// will use the default options if an overriden is not passed
BarcodeReadOptions[] readOptions =
{
oneDReadOptions, fourStateReadOptions, postNetPlanetReadOptions, gs1StackedReadOptions, patchCodeReadOptions, pdf417ReadOptions, microPdf417ReadOptions
};
return readOptions;
}
static class LEAD_VARS
{
public const string ImagesDir = @"C:\Users\Public\Documents\LEADTOOLS Images";
}
// This class holds the data we will pass to each thread
public class MyThreadData
{
// This worker thread name
public string Name;
// Barcode reader instance
public BarcodeReader BarcodeReaderInstance;
// Array of options to use
public BarcodeReadOptions[] ReadOptions;
// Image file name containing the barcodes
public string ImageFileName;
// Image containing the barcodes
public RasterImage Image;
// This will hold the barcodes found
public BarcodeData[] Barcodes;
// In case of errors
public Exception Error;
// Event to notify when the thread is finished
public AutoResetEvent FinishedEvent;
}
[Asynchronous]
public void BarcodeReaderReadBarcodeExample6()
{
BarcodeReader_ReadBarcodeExample6();
EnqueueTestComplete();
}
public void BarcodeReader_ReadBarcodeExample6()
{
RasterImage[] images = new RasterImage[2];
string originalImageFileName = "Barcode1.tif";
string rotatedImageFileName = "Barcode1_Rotated90.tif";
string[] imageFileNames = new string[] { originalImageFileName, rotatedImageFileName };
using (SampleImageStream outputStream = new SampleImageStream("Barcode1_Rotated90.tif"))
{
images[0] = SampleImage.Get(SampleImageNames.Barcode1_tif).Clone();
images[1] = SampleImage.Get(SampleImageNames.Barcode1_tif).Clone();
RotateImage(images[1]);
// Create a Barcode engine
BarcodeEngine engine = new BarcodeEngine();
// Get the Barcode reader instance
BarcodeReader reader = engine.Reader;
// Get a version of all read options that support rotated barcodes
BarcodeReadOptions[] verticalBarcodeReadOptions = GetVerticalReadBarcodeOptions(reader);
// Synchronization events
AutoResetEvent[] finishedEvents = new AutoResetEvent[2];
// Create the thread data objects
MyThreadData[] threadsData = new MyThreadData[2];
for (int i = 0; i < threadsData.Length; i++)
{
finishedEvents[i] = new AutoResetEvent(false);
threadsData[i] = new MyThreadData();
threadsData[i].BarcodeReaderInstance = reader;
threadsData[i].ReadOptions = null;
threadsData[i].FinishedEvent = finishedEvents[i];
}
// Setup the read options for the two threads
threadsData[0].Name = "Read Default Options Thread";
threadsData[0].ReadOptions = null; // Default, or horizontal
threadsData[1].Name = "Read Vertical Barcodes Thread";
threadsData[1].ReadOptions = verticalBarcodeReadOptions;
List<BarcodeData> totalBarcodes = new List<BarcodeData>();
// Now loop through all the images and try to read the barcodes with both threads at the same time
int index = 0;
foreach (RasterImage image in images)
{
Console.WriteLine("Reading barcodes from {0}", imageFileNames[index]);
for (int i = 0; i < 2; i++)
{
// Clear the previous results (if any), set up the file name and run
threadsData[i].Barcodes = null;
threadsData[i].Error = null;
threadsData[i].Image = image;
threadsData[i].ImageFileName = imageFileNames[index];
ThreadPool.QueueUserWorkItem(new WaitCallback(ReadBarcodesInThread), threadsData[i]);
}
// Wait till all the threads finishes
WaitHandle.WaitAll(finishedEvents);
// Add the barcodes found to our list
for (int i = 0; i < 2; i++)
{
if (threadsData[i].Error != null)
{
Console.WriteLine("{0} had error {1}", threadsData[i].Name, threadsData[i].Error);
}
else if (threadsData[i].Barcodes != null)
{
totalBarcodes.AddRange(threadsData[i].Barcodes);
}
}
index++;
}
// We are done, show the total number of barcodes read
Console.WriteLine("Done. Total barcodes read: {0}", totalBarcodes.Count);
}
}
private static void ReadBarcodesInThread(object state)
{
MyThreadData threadData = state as MyThreadData;
Console.WriteLine("{0} is reading the barcodes", threadData.Name);
try
{
// Load the image
RasterCodecs codecs = new RasterCodecs();
using(RasterImage image = codecs.Load(threadData.ImageFileName, 0, CodecsLoadByteOrder.BgrOrGray, 1, 1))
{
// Read the barcodes using our options
threadData.Barcodes = threadData.BarcodeReaderInstance.ReadBarcodes(image, LogicalRectangle.Empty, 0, null, threadData.ReadOptions);
}
Console.WriteLine("{0} has read {1} barcodes", threadData.Name, threadData.Barcodes.Length);
}
catch(Exception ex)
{
// Return the error to main
threadData.Error = ex;
}
finally
{
// Tell main we are done
threadData.FinishedEvent.Set();
}
}
private static void RotateImage(RasterImage image)
{
// Create a 90 degrees rotated version of Barcode1.tif
RasterCodecs codecs = new RasterCodecs();
RotateCommand rotate = new RotateCommand(90 * 100, RotateCommandFlags.Resize, RasterColor.FromKnownColor(RasterKnownColor.White));
rotate.Run(image);
}
private static BarcodeReadOptions[] GetVerticalReadBarcodeOptions(BarcodeReader reader)
{
// By default, the options read horizontal barcodes only, create an array of options capable of reading vertical barcodes
// Notice, we cloned the default options in reader so we will not change the original options
OneDBarcodeReadOptions oneDReadOptions = reader.GetDefaultOptions(BarcodeSymbology.UPCA).Clone() as OneDBarcodeReadOptions;
oneDReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
FourStateBarcodeReadOptions fourStateReadOptions = reader.GetDefaultOptions(BarcodeSymbology.USPS4State).Clone() as FourStateBarcodeReadOptions;
fourStateReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
PostNetPlanetBarcodeReadOptions postNetPlanetReadOptions = reader.GetDefaultOptions(BarcodeSymbology.PostNet).Clone() as PostNetPlanetBarcodeReadOptions;
postNetPlanetReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
GS1DatabarStackedBarcodeReadOptions gs1StackedReadOptions = reader.GetDefaultOptions(BarcodeSymbology.GS1DatabarStacked).Clone() as GS1DatabarStackedBarcodeReadOptions;
gs1StackedReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
PatchCodeBarcodeReadOptions patchCodeReadOptions = reader.GetDefaultOptions(BarcodeSymbology.PatchCode).Clone() as PatchCodeBarcodeReadOptions;
patchCodeReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
PDF417BarcodeReadOptions pdf417ReadOptions = reader.GetDefaultOptions(BarcodeSymbology.PDF417).Clone() as PDF417BarcodeReadOptions;
pdf417ReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
MicroPDF417BarcodeReadOptions microPdf417ReadOptions = reader.GetDefaultOptions(BarcodeSymbology.MicroPDF417).Clone() as MicroPDF417BarcodeReadOptions;
microPdf417ReadOptions.SearchDirection = BarcodeSearchDirection.Vertical;
// Even though this array will not contain all options, it should be enough to read all barcodes, since the version of ReadBarcodes we will use
// will use the default options if an overriden is not passed
BarcodeReadOptions[] readOptions =
{
oneDReadOptions, fourStateReadOptions, postNetPlanetReadOptions, gs1StackedReadOptions, patchCodeReadOptions, pdf417ReadOptions, microPdf417ReadOptions
};
return readOptions;
}
' This class holds the data we will pass to each thread
Public Class MyThreadData
' This worker thread name
Public Name As String
' Barcode reader instance
Public BarcodeReaderInstance As BarcodeReader
' Array of options to use
Public ReadOptions As BarcodeReadOptions()
' Image file name containing the barcodes
Public ImageFileName As String
' Image containing the barcodes
Public Image As RasterImage
' This will hold the barcodes found
Public Barcodes As BarcodeData()
' In case of errors
Public [Error] As Exception
' Event to notify when the thread is finished
Public FinishedEvent As AutoResetEvent
End Class
<TestMethod(), Asynchronous()> _
Public Sub BarcodeReaderReadBarcodeExample6()
BarcodeReader_ReadBarcodeExample6()
EnqueueTestComplete()
End Sub
Public Sub BarcodeReader_ReadBarcodeExample6()
Dim images As RasterImage() = New RasterImage(1) {}
Dim originalImageFileName As String = "Barcode1.tif"
Dim rotatedImageFileName As String = "Barcode1_Rotated90.tif"
Dim imageFileNames As String() = New String() {originalImageFileName, rotatedImageFileName}
Using outputStream As SampleImageStream = New SampleImageStream("Barcode1_Rotated90.tif")
images(0) = SampleImage.Get(SampleImageNames.Barcode1_tif).Clone()
images(1) = SampleImage.Get(SampleImageNames.Barcode1_tif).Clone()
RotateImage(images(1))
' Create a Barcode engine
Dim engine As BarcodeEngine = New BarcodeEngine()
' Get the Barcode reader instance
Dim reader As BarcodeReader = engine.Reader
' Get a version of all read options that support rotated barcodes
Dim verticalBarcodeReadOptions As BarcodeReadOptions() = GetVerticalReadBarcodeOptions(reader)
' Synchronization events
Dim finishedEvents As AutoResetEvent() = New AutoResetEvent(1) {}
' Create the thread data objects
Dim threadsData As MyThreadData() = New MyThreadData(1) {}
Dim i As Integer = 0
Do While i < threadsData.Length
finishedEvents(i) = New AutoResetEvent(False)
threadsData(i) = New MyThreadData()
threadsData(i).BarcodeReaderInstance = reader
threadsData(i).ReadOptions = Nothing
threadsData(i).FinishedEvent = finishedEvents(i)
i += 1
Loop
' Setup the read options for the two threads
threadsData(0).Name = "Read Default Options Thread"
threadsData(0).ReadOptions = Nothing ' Default, or horizontal
threadsData(1).Name = "Read Vertical Barcodes Thread"
threadsData(1).ReadOptions = verticalBarcodeReadOptions
Dim totalBarcodes As List(Of BarcodeData) = New List(Of BarcodeData)()
' Now loop through all the images and try to read the barcodes with both threads at the same time
Dim index As Integer = 0
For Each image As RasterImage In images
Console.WriteLine("Reading barcodes from {0}", imageFileNames(index))
For i = 0 To 1
' Clear the previous results (if any), set up the file name and run
threadsData(i).Barcodes = Nothing
threadsData(i).Error = Nothing
threadsData(i).Image = image
threadsData(i).ImageFileName = imageFileNames(index)
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf ReadBarcodesInThread), threadsData(i))
Next i
' Wait till all the threads finishes
WaitHandle.WaitAll(finishedEvents)
' Add the barcodes found to our list
For i = 0 To 1
If Not threadsData(i).Error Is Nothing Then
Console.WriteLine("{0} had error {1}", threadsData(i).Name, threadsData(i).Error)
ElseIf Not threadsData(i).Barcodes Is Nothing Then
totalBarcodes.AddRange(threadsData(i).Barcodes)
End If
Next i
index += 1
Next image
' We are done, show the total number of barcodes read
Console.WriteLine("Done. Total barcodes read: {0}", totalBarcodes.Count)
End Using
End Sub
Private Shared Sub ReadBarcodesInThread(ByVal state As Object)
Dim threadData As MyThreadData = TryCast(state, MyThreadData)
Console.WriteLine("{0} is reading the barcodes", threadData.Name)
Try
' Load the image
Dim codecs As RasterCodecs = New RasterCodecs()
Using image As RasterImage = codecs.Load(threadData.ImageFileName, 0, CodecsLoadByteOrder.BgrOrGray, 1, 1)
' Read the barcodes using our options
threadData.Barcodes = threadData.BarcodeReaderInstance.ReadBarcodes(image, LogicalRectangle.Empty, 0, Nothing, threadData.ReadOptions)
End Using
Console.WriteLine("{0} has read {1} barcodes", threadData.Name, threadData.Barcodes.Length)
Catch ex As Exception
' Return the error to main
threadData.Error = ex
Finally
' Tell main we are done
threadData.FinishedEvent.Set()
End Try
End Sub
Private Shared Sub RotateImage(ByVal image As RasterImage)
' Create a 90 degrees rotated version of Barcode1.tif
Dim codecs As RasterCodecs = New RasterCodecs()
Dim rotate As RotateCommand = New RotateCommand(90 * 100, RotateCommandFlags.Resize, RasterColor.FromKnownColor(RasterKnownColor.White))
rotate.Run(image)
End Sub
Private Shared Function GetVerticalReadBarcodeOptions(ByVal reader As BarcodeReader) As BarcodeReadOptions()
' By default, the options read horizontal barcodes only, create an array of options capable of reading vertical barcodes
' Notice, we cloned the default options in reader so we will not change the original options
Dim oneDReadOptions As OneDBarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.UPCA).Clone(), OneDBarcodeReadOptions)
oneDReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
Dim fourStateReadOptions As FourStateBarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.USPS4State).Clone(), FourStateBarcodeReadOptions)
fourStateReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
Dim postNetPlanetReadOptions As PostNetPlanetBarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.PostNet).Clone(), PostNetPlanetBarcodeReadOptions)
postNetPlanetReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
Dim gs1StackedReadOptions As GS1DatabarStackedBarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.GS1DatabarStacked).Clone(), GS1DatabarStackedBarcodeReadOptions)
gs1StackedReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
Dim patchCodeReadOptions As PatchCodeBarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.PatchCode).Clone(), PatchCodeBarcodeReadOptions)
patchCodeReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
Dim pdf417ReadOptions As PDF417BarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.PDF417).Clone(), PDF417BarcodeReadOptions)
pdf417ReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
Dim microPdf417ReadOptions As MicroPDF417BarcodeReadOptions = TryCast(reader.GetDefaultOptions(BarcodeSymbology.MicroPDF417).Clone(), MicroPDF417BarcodeReadOptions)
microPdf417ReadOptions.SearchDirection = BarcodeSearchDirection.Vertical
' Even though this array will not contain all options, it should be enough to read all barcodes, since the version of ReadBarcodes we will use
' will use the default options if an overriden is not passed
Dim readOptions As BarcodeReadOptions() = {oneDReadOptions, fourStateReadOptions, postNetPlanetReadOptions, gs1StackedReadOptions, patchCodeReadOptions, pdf417ReadOptions, microPdf417ReadOptions}
Return readOptions
End Function